<script lang="ts" setup>
import { create, useTags, update, uploadImage } from "~/api/blog";
import { useAppStore } from "~/store/appStore";
import { Snackbar } from "@varlet/ui";
import { checkAuth } from "~/api/auth";
const AppStore = useAppStore();
const { artical, isDarkTheme } = toRefs(AppStore);
const editText = ref(artical.value?.text ?? "");
const isShowLogin = ref(false);
const isShowEdit = ref(false);
const { data: allTags } = await useTags();

useHead({
  title: "雪貂神社-编辑",
  meta: [
    {
      name: "description",
      content: "markdown编辑器",
    },
    {
      name: "keywords",
      content: "markdown编辑器,markdown,编辑器,博客,雪貂神社,博客编辑,雪貂",
    },
  ],
});
async function checkToken() {
  try {
    return await checkAuth();
  } catch (error) {
    Snackbar.error("请先登录");
    isShowLogin.value = true;
    return false;
  }
}

const incluedTags = computed(() => {
  return allTags.value?.data
    ?.filter((tag) => editText.value.includes(tag))
    ?.join(",");
});
async function save() {
  if (!(await checkToken())) return;
  if (!artical.value?.id) {
    // 提取出第一行作为标题
    const text = editText.value;
    const title = text.split("\n")[0];
    const desc = text.slice(text.indexOf("\n") + 1, 100);
    const tags = incluedTags.value ?? "";
    artical.value = {
      title: title.replaceAll("#", "").trim(),
      desc: desc.replaceAll("#", "").trim(),
      tags,
      text: "",
    };
  }
  isShowEdit.value = true;
}
async function uploadImg(
  files: Array<File>,
  callback: (urls: Array<string>) => void
) {
  if (!(await checkToken())) return;
  let num = 0;
  let errorNum = 0;
  files.forEach((file, index) => {
    if (file.size > 1024 * 1024 * 20) {
      Snackbar.error("图片大小不能超过20M");
      return;
    }
    Snackbar.loading(`正在上传图片...`);
    uploadImage(file)
      .then((res) => {
        callback([res.url]);
        num++;
        Snackbar.loading(
          `正在上传图片(${num + errorNum + 1}/${files.length})...`
        );
      })
      .catch((err) => {
        errorNum++;
        Snackbar.error(`第${index + 1}张图片上传失败`);
      })
      .finally(() => {
        if (num >= files.length) {
          if (errorNum) {
            Snackbar.error(`有${errorNum}张图片上传失败`);
          } else {
            Snackbar.success("图片上传完毕");
          }
        }
      });
  });
}
function submit() {
  const { id } = artical.value ?? {};
  if (id) {
    updateArtical();
    return;
  }
  addArtical();
}
function checkBlog() {
  const { title = "", desc = "" } = artical.value ?? {};
  if (!title || !title.trim()) {
    Snackbar.error("标题不能为空");
    return false;
  }
  if (!desc || !desc.trim()) {
    Snackbar.error("描述不能为空");
    return false;
  }
  if (!editText.value || !editText.value.trim()) {
    Snackbar.error("内容不能为空");
    return false;
  }
  return true;
}
async function updateArtical() {
  if (!checkBlog()) return;
  const { id = "", title = "", desc = "" } = artical.value ?? {};
  const res = await update({
    id,
    title,
    desc,
    text: editText.value,
  });
  AppStore.setArtical(res);
  Snackbar.success("更新成功");
}
async function addArtical() {
  if (!checkBlog()) return;
  const { title = "", desc = "", tags = "" } = artical.value ?? {};
  const res = await create({
    title,
    desc,
    tags,
    text: editText.value,
  });
  AppStore.setArtical(res);
  Snackbar.success("发布成功");
}
</script>

<template>
  <login v-model:show="isShowLogin"></login>
  <BlogInfo
    v-model:show="isShowEdit"
    v-model="artical"
    :tags="allTags?.data"
    @submit="submit"
  ></BlogInfo>
  <Editor
    class="editBody"
    :theme="isDarkTheme ? 'dark' : 'light'"
    v-model="editText"
    @on-save="save()"
    @on-upload-img="uploadImg"
  ></Editor>
</template>

<style lang="less" scoped>
.editBody {
  height: 100vh;
}
</style>
